#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define TASK_NUM 10

typedef void(*task_t)();
task_t tasks[TASK_NUM];

void task1()
{
    printf("非阻塞轮询期间执行任务1, pid: %d\n", getpid());
}

void task2()
{
    printf("非阻塞轮询期间执行任务2, pid: %d\n", getpid());
}

void task3()
{
    printf("非阻塞轮询期间执行任务3, pid: %d\n", getpid());
}

int AddTask(task_t t);

void InitTask()// 任务的管理代码
{
    for(int i = 0; i < TASK_NUM; i++) tasks[i] = NULL;//初始化数组都为NULL
    AddTask(task1);
    AddTask(task2);
    AddTask(task3);
}

int AddTask(task_t t)//添加任务到任务列表中
{
    int pos = 0;
    for(; pos < TASK_NUM; pos++) {//遍历到空位
        if(!tasks[pos]) break;
    }
    if(pos == TASK_NUM) return -1;//说明列表满了
    tasks[pos] = t;
    return 0;
}

void ExecuteTask()//执行列表中的任务
{
    for(int i = 0; i < TASK_NUM; i++)
    {
        if(!tasks[i]) break;
        tasks[i]();
    }
}

int main()
{
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return 1;
    }
    else if (id == 0)//子进程
    {
        int cnt = 5;
        while (cnt--)
        {
            printf("I am child, pid:%d, ppid:%d, cnt: %d\n", getpid(), getppid(), cnt);
            sleep(1);
        }
        exit(11);
    }
    else//父进程
    {
        int status = 0;
        InitTask();

        while (1)
        {                                              // 轮询
            pid_t ret = waitpid(id, &status, WNOHANG); // 非阻塞
            if (ret > 0)
            {
                if (WIFEXITED(status))
                {
                    printf("进程是正常跑完的, 退出码:%d\n", WEXITSTATUS(status));
                }
                else
                {
                    printf("进程出异常了,异常信号:%d\n",WTERMSIG(status));
                }
                break;
            }
            else if (ret < 0)
            {
                printf("wait failed!\n");
                break;
            }
            else
            {
                ExecuteTask();
                sleep(1);
            }
        }
    }

    return 12;
}
